﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using ProxyTool.Models;
using ProxyTool.Services;
using ProxyTool.Services.Utils;
using ProxyTool.Utils;

namespace ProxyTool.Setting
{
    public class SettingManagement
    {
        private const string SettingFileName = "setting.json";
        private const string ContextDatasFileName = "contextDatas.json";
        private static SettingManagement _instance;
        private static readonly object Lock = new object();
        private static readonly object InitLock = new object();
        private List<ContextData> _contextDatas;
        private bool _isInited;

        private SettingManagement()
        {
        }

        public static SettingManagement Instance
        {
            get
            {
                if (_instance != null)
                {
                    if (!_instance._isInited)
                    {
                        _instance.Initinal();
                    }

                    return _instance;
                }

                lock (Lock)
                {
                    if (_instance == null)
                    {
                        _instance = new SettingManagement();
                        _instance.Initinal();
                    }
                    else if (!_instance._isInited)
                    {
                        _instance.Initinal();
                    }

                    return _instance;
                }
            }
        }

        /// <summary>
        ///     初始化
        /// </summary>
        private void Initinal()
        {
            lock (InitLock)
            {
                if (_isInited) return;
                //加载配置
                LoadSetting();
                //初始化调试
                InitDebug();
                _isInited = true;
            }
        }

        #region 上下文

        /// <summary>
        ///     上下文数据
        /// </summary>
        public List<ContextData> ContextDatas
        {
            get
            {
                if (_contextDatas == null)
                {
                    //加载上下文数据
                    LoadContextDatas();
                }

                return _contextDatas;
            }
        }

        /// <summary>
        ///     加载上下文数据
        /// </summary>
        private void LoadContextDatas()
        {
            var contextDatasFilePath = FileHelper.GetAppFileFullName(ContextDatasFileName);
            try
            {
                if (!File.Exists(contextDatasFilePath)) return;
                string jsonString = FileHelper.ReadFile(contextDatasFilePath, Encoding.UTF8);
                _contextDatas = JsonHelper.ObjectFromJsonString<List<ContextData>>(jsonString);
            }
            catch (Exception)
            {
                // ignored
            }
            finally
            {
                if (_contextDatas == null)
                    _contextDatas = new List<ContextData>();
            }
        }

        /// <summary>
        ///     保存上下文数据集合
        /// </summary>
        public void SaveContextDatas(List<ContextData> contextDatas)
        {
            _contextDatas = contextDatas;
            string contextDatasFilePath = FileHelper.GetAppFileFullName(ContextDatasFileName);
            string jsonString = JsonHelper.ObjectToJsonString(_contextDatas);
            FileHelper.WriteFile(contextDatasFilePath, jsonString, Encoding.UTF8);
        }

        #endregion

        #region 事务调试

        /// <summary>
        ///     是否支持调试
        /// </summary>
        public bool IsSupportDebug { get; private set; }

        /// <summary>
        ///     初始化调试
        /// </summary>
        public void InitDebug()
        {
            Task.Run(() =>
            {
                string u9URI = Instance.Setting.U9URI;
                if (string.IsNullOrEmpty(u9URI))
                {
                    Instance.IsSupportDebug = false;
                    return;
                }

                try
                {
                    Instance.IsSupportDebug = DebugService.TestConnection(u9URI);
                }
                catch (Exception ex)
                {
                    Instance.IsSupportDebug = false;
                }
            });
        }

        /// <summary>
        ///     停止所有的调试
        /// </summary>
        public void StopAllDebug()
        {
            if (!Instance.IsSupportDebug) return;
            string u9URI = Instance.Setting.U9URI;
            if (string.IsNullOrEmpty(u9URI)) return;
            //停止所有事务调试
            StopAllTransactionDebug(u9URI);
            //停止所有代理Do调试
            StopAllProxyDoDebug(u9URI);
        }

        /// <summary>
        ///     停止所有事务调试
        /// </summary>
        private static void StopAllTransactionDebug(string u9URI)
        {
            Task.Run(() =>
            {
                try
                {
                    DebugService.StopAllTransactionDebug(u9URI);
                }
                catch (Exception ex)
                {
                }
            });
        }

        /// <summary>
        ///     停止所有代理Do调试
        /// </summary>
        private static void StopAllProxyDoDebug(string u9URI)
        {
            Task.Run(() =>
            {
                try
                {
                    DebugService.StopAllProxyDoDebug(u9URI);
                }
                catch (Exception ex)
                {
                }
            });
        }

        #endregion

        #region 配置

        /// <summary>
        ///     配置对象
        /// </summary>
        public SettingObject Setting { get; private set; }

        /// <summary>
        ///     加载配置
        /// </summary>
        private void LoadSetting()
        {
            var settingFilePath = FileHelper.GetAppFileFullName(SettingFileName);
            var isNeedSave = true;
            try
            {
                if (File.Exists(settingFilePath))
                {
                    var jsonString = FileHelper.ReadFile(settingFilePath, Encoding.UTF8);
                    Setting = JsonHelper.ObjectFromJsonString<SettingObject>(jsonString);
                    isNeedSave = false;
                }
            }
            catch (Exception)
            {
                // ignored
            }
            finally
            {
                if (Setting == null)
                    Setting = new SettingObject();
            }

            if (isNeedSave)
                SaveSetting();
        }

        /// <summary>
        ///     保存配置
        /// </summary>
        public void SaveSetting()
        {
            string settingFilePath = FileHelper.GetAppFileFullName(SettingFileName);
            string jsonString = JsonHelper.ObjectToJsonString(Setting);
            FileHelper.WriteFile(settingFilePath, jsonString, Encoding.UTF8);
        }

        #endregion
    }
}